import cv2
import numpy as np # 导入Python中的numpy模块

def showimg(winName,img):
    cv2.imshow(winName, img)  # 显示画布
    cv2.waitKey()
    cv2.destroyAllWindows()

def drawLine(canva):
    # 在画布上，绘制一条起点坐标为(50, 50)、终点坐标为(250, 50)、蓝色的、线条宽度为5的线段
    canva = cv2.line(canva, (50, 50), (250, 50), (255, 0, 0), 5)
    # 在画布上，绘制一条起点坐标为(50, 150)、终点坐标为(250, 150)、绿色的、线条宽度为10的线段
    canva = cv2.line(canva, (50, 150), (250, 150), (0, 255, 0), 10)
    # 在画布上，绘制一条起点坐标为(50, 250)、终点坐标为(250, 250)、红色的、线条宽度为15的线段
    canva = cv2.line(canva, (50, 250), (250, 250), (0, 0, 255), 15)
    # 在画布上，绘制一条起点坐标为(150, 50)、终点坐标为(150, 250)、黄色的、线条宽度为20的线段
    canva = cv2.line(canva, (150, 50), (150, 250), (0, 255, 255), 20)
    showimg("Lines",canva)

def drawRectangle(canva):
    # 在画布上绘制一左上角坐标为(50,50)、右下角坐标为(200,150)、青色的、线条宽度为20的矩形边框
    canva = cv2.rectangle(canvas, (50, 50), (200, 150), (255, 255, 0), 2)
    showimg("rectangle", canva)


def drawCircle(canva):
    # shape[1]表示画布的宽度，center_X表示圆心的横坐标
    # 圆心的横坐标等于画布的宽度的一半
    center_X = int(canva.shape[1] / 2)
    # shape[0]表示画布的高度，center_X表示圆心的纵坐标
    # 圆心的纵坐标等于画布的高度的一半
    center_Y = int(canva.shape[0] / 2)
    # r表示半径；其中，r的值分别为0，30，60，90和120
    for r in range(0, 150, 30):
        # 绘制一个圆心坐标为(center_X, center_Y)、半径为r、绿色的、线条宽度为5的圆形
        cv2.circle(canva, (center_X, center_Y), r, (0, 255, 0), 5)
    showimg("circle", canva)

def drawRandomCircle(canva):
    for numbers in range(0, 28):
        # 获得随机的圆心横坐标，这个横坐标在[0, 299]范围内取值
        center_X = np.random.randint(0, high=300)
        # 获得随机的圆心纵坐标，这个纵坐标在[0, 299]范围内取值
        center_Y = np.random.randint(0, high=300)
        # 获得随机的半径，这个半径在[11, 70]范围内取值
        radius = np.random.randint(11, high=71)
        # 获得随机的线条颜色，这个颜色由3个在[0, 255]范围内的随机数组成的列表表示
        color = np.random.randint(0, high=256, size=(3,)).tolist()
        # 绘制一个圆心坐标为(center_X, center_Y)、半径为radius、颜色为color的实心圆形
        cv2.circle(canva, (center_X, center_Y), radius, color, -1) # 粗细度设置为-1即为实心
    showimg("circle", canva)


def drawPolyLines(canva):
    # 按顺时针给出等腰梯形4个顶点的坐标
    # 这4个顶点的坐标构成了一个大小等于“顶点个数 * 1 * 2”的数组
    # 这个数组的数据类型为np.int32
    pts = np.array([[100, 50], [200, 50], [250, 250], [50, 250]], np.int32)
    # 在画布上根据4个顶点的坐标，绘制一个闭合的、红色的、线条宽度为5的等腰梯形边框
    canva = cv2.polylines(canva, [pts], False, (0, 0, 255), 5)
    # isClosed: 是否需要闭合
    # pts：决定绘制点的顺序
    showimg("PolyLines", canva)

def drawEnglishText(canva):
    fontStyle = cv2.FONT_HERSHEY_TRIPLEX + cv2.FONT_ITALIC
    cv2.putText(canvas, "OpenCV", (20, 70), fontStyle, 2, (0, 255, 0), 5)
    cv2.putText(canvas, "OpenCV", (20, 120), fontStyle, 2, (0, 255, 0), 5, 8, True)
    showimg("Text", canva)

def onMouse(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        print("按下左键")
    elif event == cv2.EVENT_RBUTTONDOWN:
        print("按下右键")
    elif flags == cv2.EVENT_FLAG_LBUTTON:
        print("左键拖曳")
    elif flags == cv2.EVENT_FLAG_RBUTTON:
        print("右键拖曳")


# 改变灰度值
def changeGray(value):
    # 获取滑动条的值
    value = cv2.getTrackbarPos("value", "img")
    # 改变图像的灰度值
    canvas[:] = [value, value, value]


def mouseManipulate(canva):
    canva = np.zeros((100, 600, 3), np.uint8) # 具有3通道的画布
    cv2.namedWindow("img") # 命名窗口
    cv2.createTrackbar("value", "img", 0, 255, changeGray) # 创建滑动条
    while(1):
        cv2.imshow("img", canva) # 显示画布
        key = cv2.waitKey(1)&0xFF # 获取键盘上的按键指令
        if key == 27: # 如果按下的按键是ESC
            break # 终止while循环
    cv2.destroyAllWindows() # 销毁显示的所有窗口


def mouse(canva):
    #img = cv2.imread("pen.jpg")
    cv2.namedWindow("mouse")  # 命名窗口
    cv2.setMouseCallback("mouse", onMouse)  # 回调响应函数
    cv2.imshow("mouse", canva)
    cv2.waitKey()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    # np.zeros()：创建了一个画布
    # (300, 300, 3)：一个300 x 300，具有3个颜色空间（即Red、Green和Blue）的画布
    # np.uint8：OpenCV中的灰度图像和RGB图像都是以uint8存储的，因此这里的类型也是uint8
    canvas = np.zeros((300, 300, 3), np.uint8)
    # drawLine(canvas)
    # drawRectangle(canvas)
    #drawCircle(canvas)
    #drawRandomCircle(canvas)
    #drawPolyLines(canvas)
    #drawEnglishText(canvas)
    #mouse(canvas)
    mouseManipulate(canvas)